﻿#include "pch.h"

std::map<int64_t, std::shared_ptr<TOrgFile>> OrgFileMap;
int64_t nextOrgHandle = 0x0000000002000001;
std::mutex handleOrgMutex;

int32_t getOrgMapSize()
{
	return (int32_t)OrgFileMap.size();
}

// 生成唯一的句柄
int64_t generateOrgHandle()
{
	std::lock_guard<std::mutex> lock(handleOrgMutex);
	return nextOrgHandle++;
}

// 3.4.1、创建谱图
int64_t createOrgFile_(const char *szOrgName, bool innerCall)
{
	clear_error();
	CHECK_NULL_POINTER(szOrgName, -1);
	std::shared_ptr<TOrgFile> OrgFile = std::make_shared<TOrgFile>();
	STRING_COPY(szOrgName, OrgFile.get()->Name);
	int64_t nHandle = generateOrgHandle();
	OrgFileMap.insert({nHandle, OrgFile});
	return nHandle;
}
int64_t createOrgFile(const char *szOrgName)
{
	return createOrgFile_(szOrgName, false);
}

// 3.4.2、打开谱图
int64_t openOrgFile_(const char *szFileName, bool innerCall)
{
	clear_error();
	CHECK_NULL_POINTER(szFileName, -1);
	if (!std::filesystem::exists(szFileName))
	{
		SET_ERROR_(ERR_CODE_FILE_NOT_EXISTS, ERR_MESSAGE_FILE_NOT_EXISTS, szFileName);
		return -1;
	}
	std::ifstream file(szFileName, std::ios::binary | std::ios::ate);
	if (!file.is_open())
	{
		SET_ERROR_(ERR_CODE_FILE_OPEN_FAILED, ERR_MESSAGE_FILE_OPEN_FAILED, szFileName);
		return -1;
	}

	std::streampos fileSize = file.tellg();
	file.seekg(0, std::ios::beg);

	std::unique_ptr<BYTE[]> buffer(new (std::nothrow) BYTE[static_cast<int32_t>(fileSize)]);
	if (!buffer)
	{
		SET_ERROR_(ERR_CODE_MEM_ALLOC_FAILED, ERR_MESSAGE_MEM_ALLOC_FAILED, "buffer");
		file.close();
		return -1;
	}

	file.read(reinterpret_cast<char *>(buffer.get()), fileSize);
	file.close();

	if (file.gcount() != fileSize)
	{
		SET_ERROR_(ERR_CODE_FILE_READ_FAILED, ERR_MESSAGE_FILE_READ_FAILED, szFileName);
		return -1;
	}

	std::shared_ptr<TOrgFile> OrgFile = std::make_shared<TOrgFile>();
	int64_t nHandle = -1;
	try
	{
		bool success = OrgFile.get()->copyFromBuffer(buffer.get(), fileSize);
		if (!success)
		{
			SET_ERROR_(ERR_CODE_FILE_PARSE_FAILED, ERR_MESSAGE_FILE_PARSE_FAILED, szFileName);
			return -1;
		}
		nHandle = generateOrgHandle();
		OrgFileMap.insert({nHandle, OrgFile});
	}
	CATCH_AND_RETURN(-1);
	return nHandle;
}
int64_t openOrgFile(const char *szFileName)
{
	return openOrgFile_(szFileName, false);
}

// 3.4.3、存储谱图
bool saveOrgFile_(int64_t nHandle, const char *szFileName, bool innerCall)
{
	clear_error();
	CHECK_ORG_HANDLE(nHandle);
	CHECK_NULL_POINTER(szFileName, false);

	// 获取对应的 TOrgFile 实例
	std::shared_ptr<TOrgFile> &OrgFile = OrgFileMap[nHandle];

	// 计算所需的缓冲区大小
	int32_t bufferSize = OrgFile.get()->getTotalLength();
	std::vector<unsigned char> buffer(bufferSize);

	try
	{
		// 将 TOrgFile 实例复制到缓冲区
		if (!OrgFile.get()->copyToBuffer(buffer.data(), bufferSize))
		{
			SET_ERROR_(ERR_CODE_FILE_OPEN_FAILED, ERR_MESSAGE_FILE_OPEN_FAILED, szFileName);
			return false;
		}

		// 打开文件以二进制写入模式
		std::ofstream file(szFileName, std::ios::binary);
		if (!file.is_open())
		{
			SET_ERROR_(ERR_CODE_FILE_OPEN_FAILED, ERR_MESSAGE_FILE_OPEN_FAILED, szFileName);
			return false;
		}

		// 将缓冲区内容写入文件
		file.write(reinterpret_cast<const char *>(buffer.data()), bufferSize);

		// 关闭文件
		file.close();
	}
	CATCH_AND_RETURN(false);
	return true;
}
bool saveOrgFile(int64_t nHandle, const char *szFileName)
{
	return saveOrgFile_(nHandle, szFileName, false);
}

// 3.4.4、关闭谱图
bool closeOrgFile_(int64_t nHandle, bool innerCall)
{
	clear_error();
	CHECK_ORG_HANDLE(nHandle);
	OrgFileMap.erase(nHandle);
	return true;
}
bool closeOrgFile(int64_t nHandle)
{
	return closeOrgFile_(nHandle, false);
}

// 3.4.5、获取谱图基础数据
bool getOrgHead_(int64_t nHandle, TOrgHead *pBuffer, bool innerCall)
{
	clear_error();
	CHECK_ORG_HANDLE(nHandle);
	CHECK_NULL_POINTER(pBuffer, false);
	// 获取对应的 TOrgFile 实例
	std::shared_ptr<TOrgFile> &OrgFile = OrgFileMap[nHandle];
	*pBuffer = *(TOrgHead *)OrgFile.get();
	return true;
}
bool getOrgHead(int64_t nHandle, TOrgHead *pBuffer)
{
	return getOrgHead_(nHandle, pBuffer, false);
}
TOrgHead *getOrgHeadDirect(int64_t nHandle)
{
	if (OrgFileMap.contains(nHandle))
	{
		return (TOrgHead *)OrgFileMap[nHandle].get();
	}
	return nullptr;
}

// 3.4.6、设置谱图基础数据
bool setOrgHead_(int64_t nHandle, TOrgHead *pBuffer, bool innerCall)
{
	clear_error();
	CHECK_ORG_HANDLE(nHandle);
	CHECK_NULL_POINTER(pBuffer, false);
	// 获取对应的 TOrgFile 实例
	std::shared_ptr<TOrgFile> &OrgFile = OrgFileMap[nHandle];
	*(TOrgHead *)OrgFile.get() = *pBuffer;
	return true;
}
bool setOrgHead(int64_t nHandle, TOrgHead *pBuffer)
{
	return setOrgHead_(nHandle, pBuffer, false);
}

// 3.4.7、获取谱图仪器条件
bool getOrgInstCond_(int64_t nHandle, int32_t nSigChannel, TInstCond *pBuffer, bool innerCall)
{
	clear_error();
	CHECK_ORG_HANDLE(nHandle);
	CHECK_ORG_HANDLE_SAMPLING(nHandle);
	CHECK_NULL_POINTER(pBuffer, false);
	// 获取对应的 TOrgFile 实例
	std::shared_ptr<TOrgFile> &OrgFile = OrgFileMap[nHandle];
	CHECK_ORG_CHANNEL(nSigChannel);
	TInstCond blankInstCond;
	// 清空仪器条件pBuffer
	*pBuffer = blankInstCond;
	// 如果有仪器条件，则赋值给仪器条件pBuffer
	TInstCond *myInstCond = OrgFile.get()->InstCond[nSigChannel].get();
	if (myInstCond != nullptr)
	{
		*pBuffer = *myInstCond;
	}
	else
	{
		SET_ERROR_(ERR_CODE_ORG_HAS_NOT_INSTCOND, ERR_MESSAGE_ORG_HAS_NOT_INSTCOND, nHandle, nSigChannel);
		return false;
	}
	return true;
}
bool getOrgInstCond(int64_t nHandle, int32_t nSigChannel, TInstCond *pBuffer)
{
	return getOrgInstCond_(nHandle, nSigChannel, pBuffer, false);
}

// 3.4.8、设置谱图仪器条件
bool setOrgInstCond_(int64_t nHandle, int32_t nSigChannel, TInstCond *pBuffer, bool innerCall)
{
	clear_error();
	CHECK_ORG_HANDLE(nHandle);
	CHECK_ORG_HANDLE_SAMPLING(nHandle);
	CHECK_NULL_POINTER(pBuffer, false);
	// 获取对应的 TOrgFile 实例
	std::shared_ptr<TOrgFile> &OrgFile = OrgFileMap[nHandle];
	CHECK_ORG_CHANNEL(nSigChannel);
	if (OrgFile.get()->InstCond[nSigChannel].get() == nullptr)
	{
		OrgFile.get()->InstCond[nSigChannel] = std::make_shared<TInstCond>();
	}
	*OrgFile.get()->InstCond[nSigChannel].get() = *pBuffer;
	OrgFile.get()->InstCondLength[nSigChannel] = sizeof(TInstCond);
	return true;
}
bool setOrgInstCond(int64_t nHandle, int32_t nSigChannel, TInstCond *pBuffer)
{
	return setOrgInstCond_(nHandle, nSigChannel, pBuffer, false);
}

// 定义通用的GET函数宏
#define DEFINE_ORG_GET_FUNCTION(funcName, DataType, DataArray, CountArray, ErrCode, ErrMessage)                                          \
	bool funcName##_(int64_t nHandle, int32_t nSigChannel, DataType *pBuffer, int32_t nBufferCount, int32_t *pDataCount, bool innerCall) \
	{                                                                                                                                    \
		clear_error();                                                                                                                   \
		CHECK_ORG_HANDLE(nHandle);                                                                                                       \
		CHECK_ORG_HANDLE_SAMPLING(nHandle);                                                                                              \
		CHECK_NULL_POINTER(pDataCount, false);                                                                                           \
		CHECK_NULL_POINTER(pBuffer, false);                                                                                              \
		std::shared_ptr<TOrgFile> &OrgFile = OrgFileMap[nHandle];                                                                        \
		CHECK_ORG_CHANNEL(nSigChannel);                                                                                                  \
		std::shared_ptr<DataType[]> &pArray = OrgFile.get()->DataArray[nSigChannel];                                                     \
		*pDataCount = OrgFile.get()->CountArray[nSigChannel];                                                                            \
		if (nBufferCount < *pDataCount)                                                                                                  \
		{                                                                                                                                \
			SET_ERROR_(ERR_CODE_BUFFER_INSUFFICIENT, ERR_MESSAGE_BUFFER_INSUFFICIENT, "pBuffer", 1L * sizeof(DataType) * nBufferCount,   \
					   1L * sizeof(DataType) * *pDataCount);                                                                             \
			return false;                                                                                                                \
		}                                                                                                                                \
		if (*pDataCount > 0)                                                                                                             \
		{                                                                                                                                \
			if (pArray.get() == nullptr)                                                                                                 \
			{                                                                                                                            \
				SET_ERROR_(ErrCode, ErrMessage, nHandle, nSigChannel);                                                                   \
				return false;                                                                                                            \
			}                                                                                                                            \
			std::copy(pArray.get(), pArray.get() + *pDataCount, pBuffer);                                                                \
		}                                                                                                                                \
		return true;                                                                                                                     \
	}                                                                                                                                    \
	bool funcName(int64_t nHandle, int32_t nSigChannel, DataType *pBuffer, int32_t nBufferCount, int32_t *pDataCount)                    \
	{                                                                                                                                    \
		return funcName##_(nHandle, nSigChannel, pBuffer, nBufferCount, pDataCount, false);                                              \
	}

// 定义通用的SET函数宏
#define DEFINE_ORG_SET_FUNCTION(funcName, DataType, DataArray, CountArray, MaxCount)                                                \
	bool funcName##_(int64_t nHandle, int32_t nSigChannel, const DataType *pBuffer, int32_t nBufferCount, bool innerCall)           \
	{                                                                                                                               \
		clear_error();                                                                                                              \
		CHECK_ORG_HANDLE(nHandle);                                                                                                  \
		CHECK_ORG_HANDLE_SAMPLING(nHandle);                                                                                         \
		CHECK_NULL_POINTER(pBuffer, false);                                                                                         \
		std::shared_ptr<TOrgFile> &OrgFile = OrgFileMap[nHandle];                                                                   \
		CHECK_ORG_CHANNEL(nSigChannel);                                                                                             \
		if (nBufferCount <= 0 || nBufferCount > MaxCount)                                                                           \
		{                                                                                                                           \
			SET_ERROR_(ERR_CODE_IPARAM_VALUE_INVALID, ERR_MESSAGE_IPARAM_VALUE_INVALID, "nBufferCount", nBufferCount, 1, MaxCount); \
			return false;                                                                                                           \
		}                                                                                                                           \
		if (OrgFile.get()->DataArray[nSigChannel].get() == nullptr)                                                                 \
		{                                                                                                                           \
			OrgFile.get()->DataArray[nSigChannel] = std::make_shared<DataType[]>(nBufferCount);                                     \
		}                                                                                                                           \
		std::copy(pBuffer, pBuffer + nBufferCount, OrgFile.get()->DataArray[nSigChannel].get());                                    \
		OrgFile.get()->CountArray[nSigChannel] = nBufferCount;                                                                      \
		return true;                                                                                                                \
	}                                                                                                                               \
	bool funcName(int64_t nHandle, int32_t nSigChannel, const DataType *pBuffer, int32_t nBufferCount)                              \
	{                                                                                                                               \
		return funcName##_(nHandle, nSigChannel, pBuffer, nBufferCount, false);                                                     \
	}

// 使用宏定义各个函数
DEFINE_ORG_GET_FUNCTION(getOrgRawData, TRawItem, RawData, RawDataCount, ERR_CODE_ORG_HAS_NOT_RAWDATA, ERR_MESSAGE_ORG_HAS_NOT_RAWDATA)
DEFINE_ORG_SET_FUNCTION(setOrgRawData, TRawItem, RawData, RawDataCount, MAX_DOTS)

DEFINE_ORG_GET_FUNCTION(getOrgAnalResult, TAnalResult, AnalResult, AnalResultCount, ERR_CODE_ORG_HAS_NOT_ANAYRESULT, ERR_MESSAGE_ORG_HAS_NOT_ANAYRESULT)
DEFINE_ORG_SET_FUNCTION(setOrgAnalResult, TAnalResult, AnalResult, AnalResultCount, MAX_ANAL_RESULTS)

DEFINE_ORG_GET_FUNCTION(getOrgSynResult, TSynResult, SynResult, SynResultCount, ERR_CODE_ORG_HAS_NOT_SYNCRESULT, ERR_MESSAGE_ORG_HAS_NOT_SYNCRESULT)
DEFINE_ORG_SET_FUNCTION(setOrgSynResult, TSynResult, SynResult, SynResultCount, MAX_ANAL_RESULTS)

DEFINE_ORG_GET_FUNCTION(getOrgStudyData, TRawItem, StudyData, StudyDataCount, ERR_CODE_ORG_HAS_NOT_STUDYDATA, ERR_MESSAGE_ORG_HAS_NOT_STUDYDATA)
DEFINE_ORG_SET_FUNCTION(setOrgStudyData, TRawItem, StudyData, StudyDataCount, MAX_DOTS)

DEFINE_ORG_GET_FUNCTION(getOrgBlankData, TRawItem, BlankData, BlankDataCount, ERR_CODE_ORG_HAS_NOT_BLANKDATA, ERR_MESSAGE_ORG_HAS_NOT_BLANKDATA)
DEFINE_ORG_SET_FUNCTION(setOrgBlankData, TRawItem, BlankData, BlankDataCount, MAX_DOTS)

DEFINE_ORG_GET_FUNCTION(getOrgBlankResult, TAnalResult, BlankResult, BlankResultCount, ERR_CODE_ORG_HAS_NOT_BLANKRESULT, ERR_MESSAGE_ORG_HAS_NOT_BLANKRESULT)
DEFINE_ORG_SET_FUNCTION(setOrgBlankResult, TAnalResult, BlankResult, BlankResultCount, MAX_ANAL_RESULTS)

#include "MethodFile.h"
std::mutex analysisMutex;

// 组分排序
int32_t comparIDTList(const void *a, const void *b)
{
	TDLLIDTListItem *p1 = (TDLLIDTListItem *)a;
	TDLLIDTListItem *p2 = (TDLLIDTListItem *)b;
	if (p1->band >= p1->Time && p2->band >= p2->Time)
	{
		// p1、p2都是连续组
		if (p1->Time <= p2->Time && p1->Time + p1->band >= p2->Time + p2->band)
		{
			// p1包含p2
			return 1;
		}
		else if (p2->band <= p1->band && p2->band + p2->Time >= p1->band + p1->Time)
		{
			// p2包含p1
			return -1;
		}
		else if (p1->band >= p2->band)
		{
			return 1;
		}
		else
		{
			return -1;
		}
	}
	else if (p1->band >= p1->Time || p2->band >= p2->Time)
	{
		// p1、p2有一个是连续组
		if (p1->band >= p1->Time)
		{
			return 1;
		}
		else
		{
			return -1;
		}
	}
	else
	{
		// 没有连续组
		if (p1->Time > p2->Time)
		{
			return 1;
		}
		else
		{
			return -1;
		}
	}
	return 0;
}

// 提取谱图数据
bool fetchRawData(int64_t nHandle, int32_t chn, std::vector<int32_t> &DataItems)
{
	std::shared_ptr<TOrgHead> orgHead = std::make_shared<TOrgHead>();
	if (!getOrgHead_(nHandle, orgHead.get()))
	{
		PUSH_ERROR("函数 fetchRawData 调用 getOrgHead 失败。");
		return false;
	}
	int32_t rawItemCount = orgHead.get()->RawDataCount[chn];
	int32_t realRawCount = 0;
	std::unique_ptr<TRawItem[]> pRawItem = std::make_unique<TRawItem[]>(rawItemCount);
	if (!getOrgRawData_(nHandle, chn, pRawItem.get(), rawItemCount, &realRawCount) || realRawCount != rawItemCount)
	{
		PUSH_ERROR("函数 fetchRawData 调用 getOrgRawData_ 失败。");
		return false;
	}
	for (int32_t i = 0; i < rawItemCount; i++)
	{
		DataItems.push_back(pRawItem.get()[i].Data);
	}
	return true;
}

// 提取谱图方法数据
bool fetchMethodHead(int64_t nHandle, int64_t nMethodHandle, TMethodHead *pOrgHead)
{
	if (nMethodHandle == -1)
	{
		if (!getMethodHead_(nHandle, ORG_HANDLE, pOrgHead))
		{
			PUSH_ERROR("函数 fetchMethodHead 调用 getMethodHead_ 失败。");
			return false;
		}
	}
	else
	{
		if (MethodFileMap.count(nMethodHandle) <= 0)
		{
			PUSH_ERROR(ERR_MESSAGE_METHOD_HANDLE_NOT_EXIST, nMethodHandle);
			return false;
		}
		if (!getMethodHead_(nMethodHandle, METHOD_HANDLE, pOrgHead))
		{
			PUSH_ERROR("函数 fetchMethodHead 调用 getMethodHead_ 失败。");
			return false;
		}
	}
	return true;
}

// 提取谱图方法组分数据
bool fetchMethodCompList(int64_t nHandle, int64_t nMethodHandle, int32_t chn, TUkPkFactor &UkPkFactor,
						 int32_t &DLLIDTListItemLength, std::unique_ptr<TDLLIDTListItem[]> &DLLIDTListItem, int32_t nBufferCount)
{
	int32_t compCount = 0;
	std::shared_ptr<TCompList[]> pCompList = std::make_unique<TCompList[]>(B512);
	if (nMethodHandle == -1)
	{
		if (!getMethodCompList_(nHandle, ORG_HANDLE, pCompList.get(), B512, &compCount))
		{
			PUSH_ERROR("函数 fetchMethodCompList 调用 getMethodCompList_ 失败。");
			return false;
		}
	}
	else
	{
		if (!getMethodCompList_(nMethodHandle, METHOD_HANDLE, pCompList.get(), B512, &compCount))
		{
			PUSH_ERROR("函数 fetchMethodCompList 调用 getMethodCompList_ 失败。");
			return false;
		}
	}
	DLLIDTListItemLength = 0;
	for (int32_t i = 0; i < compCount; i++)
	{
		if (pCompList.get()[i].channelNo == chn)
		{
			int32_t j = DLLIDTListItemLength++;
			if (j >= nBufferCount)
			{
				break;
			}
			DLLIDTListItem.get()[j] = pCompList.get()[i];
			// TODO 重算istdNoSelf、istdNoSelf、UkPkFactor.type
		}
	}

	for (int32_t i = 0; i < DLLIDTListItemLength; i++)
	{
		DLLIDTListItem.get()[i].Reserve = i;
	}
	// 按保留时间对组分重新进行排序
	qsort(DLLIDTListItem.get(), DLLIDTListItemLength, sizeof(TDLLIDTListItem), comparIDTList);
	// 重算istdNoSelf、istdNoSelf、UkPkFactor.type
	int32_t changed[B512] = {0};
	for (int32_t i = 0; i < B512; i++)
	{
		changed[i] = 0;
	}
	for (int32_t i = 0; i < DLLIDTListItemLength; i++)
	{
		if (DLLIDTListItem.get()[i].istdNoSelf != 0)
		{
			for (int32_t j = 0; j < DLLIDTListItemLength; j++)
			{
				if (changed[j] == 0 && j != i && DLLIDTListItem.get()[j].istdNoUsed == DLLIDTListItem.get()[i].istdNoSelf)
				{
					DLLIDTListItem.get()[j].istdNoUsed = i + 1;
					changed[j] = 1;
				}
			}
			DLLIDTListItem.get()[i].istdNoSelf = i + 1;
		}
		if (UkPkFactor.type == DLLIDTListItem.get()[i].Reserve + 2)
		{
			UkPkFactor.type = i + 2;
		}
	}
	return true;
}

// 提取谱图方法分组数据
bool fetchMethodGroupList(int64_t nHandle, int64_t nMethodHandle, int32_t chn,
						  int32_t &DLLGROUPListItemLength, std::unique_ptr<TGroupList[]> &DLLGROUPListItem, int32_t nBufferCount)
{
	int32_t groupCount = 0;
	std::unique_ptr<TGroupList[]> pGroupList = std::make_unique<TGroupList[]>(B512);
	if (nMethodHandle == -1)
	{
		if (!getMethodGroupList_(nHandle, ORG_HANDLE, pGroupList.get(), B512, &groupCount))
		{
			PUSH_ERROR("函数 fetchMethodGroupList 调用 getMethodGroupList_ 失败。");
			return false;
		}
	}
	else
	{
		if (!getMethodGroupList_(nMethodHandle, METHOD_HANDLE, pGroupList.get(), B512, &groupCount))
		{
			PUSH_ERROR("函数 fetchMethodGroupList 调用 getMethodGroupList_ 失败。");
			return false;
		}
	}
	DLLGROUPListItemLength = 0;
	for (int32_t i = 0; i < groupCount; i++)
	{
		TGroupList *pGroupItem = &pGroupList.get()[i];
		if (pGroupItem->channelNo == chn)
		{
			int32_t j = DLLGROUPListItemLength++;
			if (j >= nBufferCount)
			{
				break;
			}
			DLLGROUPListItem[DLLGROUPListItemLength++] = *pGroupItem;
		}
	}
	return true;
}

// 提取谱图方法事件表数据
bool fetchMethodEventList(int64_t nHandle, int64_t nMethodHandle, int32_t chn,
						  int32_t &DLLTPRGListItemLength, std::unique_ptr<TDLLTPRGListItem[]> &DLLTPRGListItem, int32_t nBufferCount)
{
	int32_t eventCount;
	std::unique_ptr<TEventList[]> pEventList = std::make_unique<TEventList[]>(B512);
	if (nMethodHandle == -1)
	{
		if (!getMethodEventList_(nHandle, ORG_HANDLE, pEventList.get(), B512, &eventCount))
		{
			PUSH_ERROR("函数 fetchMethodEventList 调用 getMethodEventList_ 失败。");
			return false;
		}
	}
	else
	{
		if (!getMethodEventList_(nMethodHandle, METHOD_HANDLE, pEventList.get(), B512, &eventCount))
		{
			PUSH_ERROR("函数 fetchMethodEventList 调用 getMethodEventList_ 失败。");
			return false;
		}
	}
	DLLTPRGListItemLength = 0;
	for (int32_t eventIdx = 0; eventIdx < eventCount; eventIdx++)
	{
		TEventList *pEvent = &pEventList.get()[eventIdx];
		// 小于等于BASE_MERGE_UPMOST_的手动事件丢入积分模块计算。
		if (pEvent->enable && pEvent->channelNo == chn && pEvent->event <= BASE_MERGE_UPMOST_)
		{
			int32_t j = DLLTPRGListItemLength++;
			if (j >= nBufferCount)
			{
				break;
			}
			DLLTPRGListItem.get()[j].ts = pEvent->ts;
			DLLTPRGListItem.get()[j].te = pEvent->te;
			DLLTPRGListItem.get()[j].event = pEvent->event;
			DLLTPRGListItem.get()[j].paraValue = pEvent->paraValue;
		}
	}
	return true;
}

// 一元一次方程求解 ax + b = 0
double solveLinearEquation(double a, double b)
{
	if (a == 0)
	{
		return 0; // 无解或无穷多解
	}
	double root = -b / a;
	return root;
}

// 一元二次方程求解 ax² + bx + c = 0
double solveQuadraticEquation(double a, double b, double c)
{
	if (a == 0)
	{
		return solveLinearEquation(b, c); // 退化为一元一次方程
	}

	double discriminant = b * b - 4 * a * c;

	if (discriminant < 0)
	{
		return 0; // 无实数根
	}

	double root1 = (-b + sqrt(discriminant)) / (2 * a);
	double root2 = (-b - sqrt(discriminant)) / (2 * a);

	// 优先返回正数根
	if (root1 > 0)
		return root1;
	if (root2 > 0)
		return root2;
	// 如果都是负数，返回较大的那个(更接近0)
	return MAX(root1, root2);
}

// 一元三次方程求解 ax³ + bx² + cx + d = 0
double solveCubicEquation(double a, double b, double c, double d)
{
	if (a == 0)
	{
		return solveQuadraticEquation(b, c, d); // 退化为一元二次方程
	}

	// 归一化为 x³ + px² + qx + r = 0
	double p = b / a;
	double q = c / a;
	double r = d / a;

	// 使用Cardano公式
	double Q = (3 * q - p * p) / 9;
	double R = (9 * p * q - 27 * r - 2 * p * p * p) / 54;
	double D = Q * Q * Q + R * R; // 判别式

	std::vector<double> realRoots;

	if (D > 0)
	{ // 一个实根，两个复根
		double S = cbrt(R + sqrt(D));
		double T = cbrt(R - sqrt(D));
		double root = (S + T) - p / 3;
		realRoots.push_back(root);
	}
	else if (D == 0)
	{ // 三个实根，至少两个相等
		double root1 = 2 * cbrt(R) - p / 3;
		double root2 = -cbrt(R) - p / 3;
		realRoots.push_back(root1);
		realRoots.push_back(root2);
	}
	else
	{ // D < 0: 三个不同实根
		double theta = acos(R / sqrt(-Q * Q * Q));
		double sqrtQ = 2 * sqrt(-Q);
		double root1 = sqrtQ * cos(theta / 3) - p / 3;
		double root2 = sqrtQ * cos((theta + 2 * M_PI) / 3) - p / 3;
		double root3 = sqrtQ * cos((theta + 4 * M_PI) / 3) - p / 3;
		realRoots.push_back(root1);
		realRoots.push_back(root2);
		realRoots.push_back(root3);
	}

	// 排序根，优先返回正数根
	sort(realRoots.begin(), realRoots.end(), [](double a, double b)
		 {
			 if (a > 0 && b > 0)
				 return a < b; // 都为正数，取较小者
			 if (a > 0)
				 return true; // a为正数，优先
			 if (b > 0)
				 return false; // b为正数，优先
			 return a > b;	   // 都为负数，取较大者
		 });

	if (!realRoots.empty())
	{
		return realRoots[0];
	}

	return 0;
}

// 计算一个积分结果的浓度值
double calcResultConc(E_BASEDON basedOn, double YUnit, int32_t CurveType, TDLLIDTListItem *pIdt, TDLLResultListItem *pRes, TUkPkFactor *pUKFactor)
{
	float f0 = 0;
	float f1 = 0;
	float f2 = 0;
	float f3 = 0;
	double y = 0;
	double conc = 0;
	if (basedOn == ON_AREA)
	{
		y = 1.0 / YUnit * pRes->Area;
	}
	else
	{
		y = 1.0 / YUnit * pRes->Height;
	}
	if (pRes->Idno != 0)
	{
		f0 = pIdt->f0;
		f1 = pIdt->f1;
		f2 = pIdt->f2;
		f3 = pIdt->f3;
	}
	else if (pUKFactor->type == 0)
	{
		f0 = 0;
		f1 = 0;
		f2 = 0;
		f3 = 0;
	}
	else if (pUKFactor->type == 1)
	{
		f0 = pUKFactor->f0;
		f1 = pUKFactor->f1;
		f2 = pUKFactor->f2;
		f3 = pUKFactor->f3;
	}
	else if (pUKFactor->type >= 2)
	{
		f0 = pIdt->f0;
		f1 = pIdt->f1;
		f2 = pIdt->f2;
		f3 = pIdt->f3;
	}
	if (f0 == 0 && f1 == 0 && f2 == 0 && f3 == 0)
	{
		conc = 0;
	}
	else
	{
		switch (CurveType)
		{
		case 0:
			conc = solveLinearEquation(f1, f0 - y);
			break;
		case 1:
			conc = solveQuadraticEquation(f2, f1, f0 - y);
			break;
		case 2:
			conc = solveCubicEquation(f3, f2, f1, f0 - y);
			break;
		default:
			break;
		}
	}
	return conc;
}

// 计算全部积分结果的浓度值
bool calcOrgResultConc(E_BASEDON basedOn, double YUnit, int32_t CurveType, TDLLIDTINF *pIdtInfo, TDLLRESINF *pResInfo, TUkPkFactor *pUKFactor)
{
	int32_t idtNum = *(pIdtInfo->num);
	int32_t resNum = *(pResInfo->num);
	TDLLIDTListItem *pIdt = pIdtInfo->head;
	TDLLResultListItem *pRes = pResInfo->head;
	for (int32_t i = 0; i < resNum; i++)
	{
		int32_t idt_index = 0;
		if (pRes[i].Idno != 0)
		{
			idt_index = pRes[i].Idno - 1;
		}
		else if (pUKFactor->type >= 2)
		{
			idt_index = pUKFactor->type - 2;
		}
		pRes[i].Conc = calcResultConc(basedOn, YUnit, CurveType, &pIdt[idt_index], &pRes[i], pUKFactor);
	}
	return true;
}

// 组分表排序还原恢复，结果表的Idno应指向未排序前的组分索引号
bool restoreIdtSortAction(TDLLIDTINF *pIdtInfo, TDLLRESINF *pResInfo)
{
	int32_t idtNum = *(pIdtInfo->num);
	int32_t resNum = *(pResInfo->num);
	TDLLIDTListItem *pIdt = pIdtInfo->head;
	TDLLResultListItem *pRes = pResInfo->head;
	for (int32_t i = 0; i < resNum; i++)
	{
		if (pRes[i].Idno != 0)
		{
			int32_t sorted_idt_index = pRes[i].Idno - 1;
			int32_t unsorted_idt_index = pIdt[sorted_idt_index].Reserve;
			pRes[i].Idno = unsorted_idt_index + 1;
		}
	}
	return true;
}

// 根据保留时间查找组分索引
int findIdtIndexByRTime(float rtime, TDLLIDTINF *pIdtInfo)
{
	int32_t idtCount = *(pIdtInfo->num);
	TDLLIDTListItem *pItem = pIdtInfo->head;

	for (int32_t i = 0; i < idtCount; i++)
	{
		if (abs(rtime - pItem[i].Time) <= 0.01)
		{
			return i;
		}
	}

	return -1;
}

// 计算水平基线积分(扩展手动事件)
bool calcHorzBaseLine(int64_t nHandle, int64_t nMethodHandle, int32_t chn, E_BASEDON basedOn, double YUnit, int32_t CurveType, TRAWBAG *pRawBag, TDLLIDTINF *pIdtInfo, TDLLRESINF *pResInfo, TUkPkFactor *pUKFactor)
{
	int32_t eventCount;
	std::unique_ptr<TEventList[]> pEventList = std::make_unique<TEventList[]>(B512);
	if (nMethodHandle == -1)
	{
		if (!getMethodEventList_(nHandle, ORG_HANDLE, pEventList.get(), B512, &eventCount))
		{
			PUSH_ERROR("函数 calcHorzBaseLine 调用 getMethodEventList_ 失败。");
			return false;
		}
	}
	else
	{
		if (!getMethodEventList_(nMethodHandle, METHOD_HANDLE, pEventList.get(), B512, &eventCount))
		{
			PUSH_ERROR("函数 calcHorzBaseLine 调用 getMethodEventList_ 失败。");
			return false;
		}
	}
	float freq = *(pRawBag->freq);
	int *head = pRawBag->head;

	bool hasHorzBase = false;

	for (int32_t eventIdx = 0; eventIdx < eventCount; eventIdx++)
	{
		TEventList *pEvent = &pEventList.get()[eventIdx];
		// 小于等于BASE_MERGE_UPMOST_的手动事件丢入积分模块计算。
		if (pEvent->enable && pEvent->channelNo == chn && pEvent->event > BASE_MERGE_UPMOST_)
		{
			// 水平基线积分(event = 40)
			if (pEvent->event == 40)
			{
				float ts = pEvent->ts;
				float te = pEvent->te;
				float h = pEvent->paraValue.f * YUnit;
				float midRTime = (ts + te) / 2;
				float w = (te - ts) / 2;

				hasHorzBase = true;

				// 移除保留时间位于[ts,te]之间的峰
				for (int i = (*pResInfo->num) - 1; i >= 0; i--)
				{
					TDLLResultListItem *pResultItem = &pResInfo->head[i];
					if (pResultItem->RTime >= ts && pResultItem->RTime <= te)
					{
						if (i != (*pResInfo->num) - 1)
						{
							memmove(&pResInfo->head[i], &pResInfo->head[i + 1], ((*pResInfo->num) - 1 - i) * sizeof(TDLLResultListItem));
						}
						(*pResInfo->num)--;
					}
				}
				int32_t tsIndex = (int32_t)(ts * 60 * freq);
				int32_t teIndex = (int32_t)(te * 60 * freq);
				double area = 0;
				double height = 0;
				float tr = 0;
				for (int32_t i = tsIndex; (i < teIndex) && (i < *pRawBag->time); i++)
				{
					double mean = (head[i] + head[i + 1]) / 2;
					if (mean - h > 0)
					{
						area += (1.0 / freq) * (mean - h);
					}
					if (head[i] > height)
					{
						height = head[i];
						tr = 1.0 * i / 60 / freq;
					}
				}
				(*pResInfo->num)++;
				TDLLResultListItem *pResultItem = &pResInfo->head[(*pResInfo->num) - 1];
				*pResultItem = TDLLResultListItem();
				pResultItem->RTime = midRTime;
				pResultItem->Area = area;
				pResultItem->Conc = 0;
				pResultItem->ts = ts;
				pResultItem->te = te;
				pResultItem->tr = tr;
				pResultItem->W50 = w;
				pResultItem->Height = height;
				pResultItem->TypeCode[0] = ' ';
				pResultItem->TypeCode[1] = 'B';
				pResultItem->TypeCode[2] = 'B';
				pResultItem->TypeCode[3] = 0;
				// 计算浓度
				int idt_index = findIdtIndexByRTime(midRTime, pIdtInfo);
				pResultItem->Idno = idt_index + 1;
				if (idt_index >= 0)
				{
					TDLLIDTListItem *pIdt = &pIdtInfo->head[idt_index];
					pResultItem->Conc = calcResultConc(basedOn, YUnit, CurveType, pIdt, pResultItem, pUKFactor);
					STRING_COPY(pIdt->Name, pResultItem->Name)
				}
				else
				{
					STRING_COPY(_S_("水平基线"), pResultItem->Name)
				}
			}
		}
	}

	if (hasHorzBase)
	{
		// 重算面积百分比
		double totalArea = 0;
		for (int i = (*pResInfo->num) - 1; i >= 0; i--)
		{
			TDLLResultListItem *pResultItem = &pResInfo->head[i];
			totalArea += pResultItem->Area;
		}
		for (int i = (*pResInfo->num) - 1; i >= 0; i--)
		{
			TDLLResultListItem *pResultItem = &pResInfo->head[i];
			pResultItem->AreaPer = 100 * pResultItem->Area / totalArea;
		}
	}
	return true;
}

// 内标组分判定
bool isIstd(int idx, TDLLIDTINF *idt_inf)
{
	if (idx < 0 || idx < *idt_inf->num)
	{
		return false;
	}
	return ((idt_inf->head[idx].istdNoUsed == 0) && (idt_inf->head[idx].istdNoSelf > 0));
}

// 连续组组分判定
bool isContGroupIdt(int idx, TDLLIDTINF *idt_inf)
{
	if (idx < 0 || idx < *idt_inf->num)
	{
		return false;
	}

	return (idt_inf->head[idx].Time < idt_inf->head[idx].band);
}

// 综合结果组分类别
int getIdtType(int idx, TDLLIDTINF *idt_inf)
{
	int nIdType = 0;
	if (idx >= 0 || idx < *idt_inf->num)
	{
		nIdType = idt_inf->head[idx].TypeEx;
		if (nIdType != ID_ISTD && nIdType != ID_RISTD)
		{
			if (isIstd(idx, idt_inf))
			{
				nIdType = ID_ISTD;
			}
		}
	}
	return nIdType;
}

int getSynItemType(int idx, TDLLIDTINF *idt_inf)
{
	int nSynItemType = 0;

	if (isContGroupIdt(idx, idt_inf))
	{
		nSynItemType = ITEM_CONT_GROUP;
	}
	else
	{
		int nIdType = getIdtType(idx, idt_inf);
		switch (nIdType)
		{
		case ID_OUTER:
			nSynItemType = ITEM_OUTER_COMP;
			break;
		case ID_SATUR:
			nSynItemType = ITEM_PRIME_COMP;
			break;
		default:
			nSynItemType = ITEM_COMPOUND;
			break;
		}
	}
	return nSynItemType;
}

int32_t indexOfIdt(std::string name, TDLLIDTINF *idt_inf)
{
	if (name.empty())
	{
		return -1;
	}

	int32_t idx = -1;

	for (int32_t i = 0; i < *idt_inf->num; i++)
	{
		if (name == std::string(idt_inf->head[i].Name))
		{
			idx = i;
			break;
		}
	}

	return idx;
}

int32_t indexOfRes(int32_t idt_index, TDLLRESINF *res_inf)
{
	if (idt_index < 0)
	{
		return -1;
	}
	for (int32_t i = 0; i < *res_inf->num; i++)
	{
		if (idt_index + 1 == res_inf->head[i].Idno)
		{
			return i;
		}
	}
	return -1;
}

bool fetchBlankInf(int64_t nHandle, int32_t chn, TDLLRESINF &blank_inf, int32_t &blank_count, std::unique_ptr<TDLLResultListItem[]> &blank_list)
{
	blank_count = 0;
	blank_inf.head = nullptr;
	blank_inf.len = B512;
	blank_inf.num = &blank_count;
	std::unique_ptr<TAnalResult[]> blankAnalysisList = std::make_unique<TAnalResult[]>(B512);
	if (!getOrgBlankResult_(nHandle, chn, &blankAnalysisList.get()[0], B512, &blank_count))
	{
		PUSH_ERROR("函数 fetchBlankInf 调用 getOrgBlankResult_ 失败。");
		return false;
	}
	blank_list = std::make_unique<TDLLResultListItem[]>(B512);
	if (blank_count > 0)
	{
		for (int32_t i = 0; i < blank_count; i++)
		{
			blank_list[i] = blankAnalysisList[i];
		}
		blank_inf.head = blank_list.get();
	}
	return true;
}

// 计算综合结果步骤一：处理组分表
bool calcSynResultForIdt(int64_t nHandle, int64_t nMethodHandle, int32_t chn, TDLLIDTINF *idt_inf, TDLLRESINF *res_inf, TUkPkFactor *uk_factor, std::vector<TSynResult> &vSynResult)
{
	std::unique_ptr<TOrgHead> orgHead = std::make_unique<TOrgHead>();
	std::unique_ptr<TMethodHead> methodHead = std::make_unique<TMethodHead>();

	if (!getOrgHead_(nHandle, orgHead.get()))
	{
		PUSH_ERROR("函数 calcSynResultForIdt 调用 getOrgHead_ 失败。");
		return false;
	}
	E_SUB_TYPE nBlankMode = orgHead.get()->BlankMode;

	if (!fetchMethodHead(nHandle, nMethodHandle, methodHead.get()))
	{
		PUSH_ERROR("函数 calcSynResultForIdt 调用 fetchMethodHead 失败。");
		return false;
	}

	E_BASEDON basedOn = methodHead.get()->EPara.based;
	E_QUANTBY quantBy = methodHead.get()->EPara.quantBy;
	double YUnit = methodHead.get()->YUnit[chn];
	int32_t CurveType = methodHead.get()->CalibHead->CurveType;
	TDLLIDTListItem *idt_list = idt_inf->head;
	TDLLResultListItem *res_list = res_inf->head;

	int idt_count = *idt_inf->num;
	if (idt_count <= 0)
	{
		return true;
	}

	// 提取综合结果组分信息
	for (int32_t i = 0; i < idt_count; i++)
	{
		if (idt_list[i].istdNoSelf == 0 && idt_list[i].TypeEx != ID_CONT_GROUP) // 内标物需除外
		{
			TSynResult synResult;
			synResult.Type = getSynItemType(i, idt_inf); // 综合结果表项目类别
			std::string idt_name = idt_list[i].Name;
			STRING_COPY(idt_name, synResult.Name);

			synResult.Tr = idt_list[i].Time;
			synResult.Band = idt_list[i].band;
			synResult.cLower = idt_list[i].cLower;
			synResult.cUpper = idt_list[i].cUpper;
			synResult.dLimit = idt_list[i].k1;
			synResult.OkState = i; // 记录idt索引
			vSynResult.push_back(synResult);
		}
	}

	int32_t blank_count = 0;
	TDLLRESINF blank_inf;
	std::unique_ptr<TDLLResultListItem[]> blank_list = std::make_unique<TDLLResultListItem[]>(B512);
	if (!fetchBlankInf(nHandle, chn, blank_inf, blank_count, blank_list))
	{
		PUSH_ERROR("函数 sumUnknownPeaks 调用 fetchBlankInf 失败。");
		return false;
	}

	for (int32_t i = 0; i < (int32_t)vSynResult.size(); i++)
	{
		double dArea = 0;
		double dHeight = 0;
		double dConc = 0;

		double dArea_ = 0;
		double dHeight_ = 0;
		double dConc_ = 0;

		TSynResult *pSynResult = &vSynResult[i];
		int32_t idt_index = pSynResult->OkState;
		int32_t res_index = indexOfRes(idt_index, res_inf);
		int32_t blank_index = indexOfRes(idt_index, &blank_inf);
		if (res_index >= 0)
		{
			dArea = res_list[res_index].Area;
			dHeight = res_list[res_index].Height;
			dConc = calcResultConc(basedOn, YUnit, CurveType, &idt_list[idt_index], &res_list[res_index], uk_factor);
		}
		if (blank_index >= 0 && nBlankMode != SUB_NONE)
		{
			dArea_ = blank_list[blank_index].Area;
			dHeight_ = blank_list[blank_index].Height;
			dConc_ = calcResultConc(basedOn, YUnit, CurveType, &idt_list[idt_index], &blank_list[blank_index], uk_factor);
			if (nBlankMode == SUB_ON_RESP)
			{
				dArea -= dArea_;
				dHeight -= dHeight_;
				TDLLResultListItem res;
				res = blank_list[blank_index];
				res.Area = dArea;
				res.Height = dHeight;
				dConc = calcResultConc(basedOn, YUnit, CurveType, &idt_list[idt_index], &res, uk_factor);
			}
			else
			{
				dArea -= dArea_;
				dHeight -= dHeight_;
				dConc -= dConc_;
			}
		}
		vSynResult[i].Area = MAX(dArea, 0.0);
		vSynResult[i].Height = MAX(dHeight, 0.0);
		vSynResult[i].Conc = MAX(dConc, 0.0);
	}
	return true;
}

int32_t IndexOfORGTr(float fTr, TDLLResultListItem *lpDLLResultList, int32_t nResultCount, float fIdtTimeOfs = 0)
{
	if (fTr <= 0 || lpDLLResultList == NULL || nResultCount <= 0)
	{
		return -1;
	}

	int32_t nIdx = -1;
	float fTri = 0;

	for (int32_t i = 0; i < nResultCount; i++)
	{
		fTri = lpDLLResultList[i].RTime - fIdtTimeOfs;

		if (fTri > fTr)
		{
			nIdx = i;
			break;
		}
	}

	if (nIdx > 0)
	{
		float fTri_1 = lpDLLResultList[nIdx - 1].RTime - fIdtTimeOfs;

		if ((fTr - fTri_1) < (fTri - fTr))
		{
			nIdx--;
		}
	}
	else if (nIdx < 0)
	{
		int32_t i = nResultCount - 1;
		fTri = lpDLLResultList[i].RTime - fIdtTimeOfs;
		float fBand = lpDLLResultList[i].W50;

		if (fabs(fTri - fTr) <= fBand)
		{
			nIdx = i;
		}
	}

	return nIdx;
}
int32_t IndexOfIdt(std::string szName, TDLLIDTINF *idt_inf)
{
	if (szName.empty())
	{
		return -1;
	}
	int32_t nIdx = -1;
	for (int32_t i = 0; i < *idt_inf->num; i++)
	{
		if (szName == idt_inf->head[i].Name)
		{
			nIdx = i;
			break;
		}
	}
	return nIdx;
}
bool CalcConcOfContinuousGroupBySub(int32_t nBlankMode, E_QUANTBY quantBy, E_BASEDON basedOn, double YUnit, int32_t CurveType, TDLLIDTINF *idt_inf, TDLLRESINF *res_inf, TDLLRESINF *blank_inf, float tLower, float tUpper, double &area, double &height, double &conc, int32_t &res_index)
{

	int32_t res_count = *res_inf->num;
	TDLLResultListItem *res_list = res_inf->head;
	area = 0;
	height = 0;
	conc = 0;
	if (res_index < 0 || res_index >= res_count)
	{
		return false;
	}

	float tr = 0;
	bool bTmp = false;
	std::string szName;

	for (int32_t i = res_index; i < res_count; i++)
	{
		tr = res_list[i].RTime;

		if (tr >= tLower && tr <= tUpper) // 在要求的时间范围中
		{
			area = res_list[i].Area;
			height = res_list[i].Height;
			conc = res_list[i].Conc;
			res_index = i;
			bTmp = true;
			szName = res_list[i].Name;

			if (!szName.empty()) // 为已知峰
			{
				i++;
				while (i < res_count && res_list[i].RTime <= tUpper)
				{
					if (szName == res_list[i].Name)
					{
						area += res_list[i].Area;
						height += res_list[i].Height;
						conc += res_list[i].Conc;
						res_index = i;
						i++;
					}
					else
					{
						break;
					}
				}
			}
			break;
		}
		else if (tr > tUpper) // 超过要求的时间范围
		{
			break;
		}
	}

	double fCaloric = 0;
	int32_t blank_count = *blank_inf->num;
	TDLLResultListItem *blank_list = blank_inf->head;
	if (bTmp && blank_count > 0) // 处理空白结果:
	{
		if (!szName.empty()) // 为已知峰时
		{
			double fArea_ = 0, fHeight_ = 0, fConc_ = 0;
			//int idx = -1;

			for (int32_t i = 0; i < blank_count; i++) // 找该已知峰，并求和
			{
				tr = blank_list[i].RTime;

				if (tr >= tLower && tr <= tUpper) // 在要求的时间范围中
				{
					if (szName == blank_list[i].Name)
					{
						fArea_ += blank_list[i].Area;
						fHeight_ += blank_list[i].Height;
						fConc_ += blank_list[i].Conc;
						//idx = i;
						i++;

						while (i < blank_count && blank_list[i].RTime <= tUpper)
						{
							if (szName == blank_list[i].Name)
							{
								fArea_ += blank_list[i].Area;
								fHeight_ += blank_list[i].Height;
								fConc_ += blank_list[i].Conc;
								i++;
							}
							else
							{
								break;
							}
						}

						break;
					}
				}
				else if (tr > tUpper) // 超过要求的时间范围
				{
					break;
				}
			}

			int32_t idt_index = IndexOfIdt(szName, idt_inf);

			if (idt_index >= 0) // 扣空白成功
			{
				if (nBlankMode == SUB_ON_RESP && quantBy != BY_NORMAL && quantBy != BY_S_FACT)
				{
					// 先扣除响应值(面积/峰高)，再在扣空后的响应值基础上计算含量：
					area -= fArea_;
					height -= fHeight_;
					TDLLResultListItem res;
					TUkPkFactor uk_factor;
					res.Area = area;
					res.Height = height;
					res.Idno = 1;
					conc = calcResultConc(basedOn, YUnit, CurveType, &idt_inf->head[idt_index], &res, &uk_factor);
				}
				else
				{
					// 直接扣除含量：
					area -= fArea_;
					height -= fHeight_;
					conc -= fConc_;
				}
			}
		}
		else
		{
			float fTr = res_list[res_index].RTime;
			int32_t idx = IndexOfORGTr(fTr, blank_list, blank_count);

			if (idx >= 0)
			{
				area -= blank_list[idx].Area;
				height -= blank_list[idx].Height;
				conc -= blank_list[idx].Conc;
			}
		}
	}

	return bTmp;
}

bool GetResp(int32_t idt_index, E_QUALITBY qualitBy, double &area, double &height, double &conc, double &areaPer, TDLLIDTINF *idt_inf, TDLLRESINF *res_inf)
{
	area = 0;
	height = 0;

	int32_t idt_count = *idt_inf->num;
	int32_t res_count = *res_inf->num;
	TDLLIDTListItem *idt_list = idt_inf->head;
	TDLLResultListItem *res_list = res_inf->head;

	if (idt_index < 0 || idt_index >= idt_count)
	{
		conc = 0;
		areaPer = 0;
		return false;
	}

	std::string idt_name = idt_list[idt_index].Name;
	float time = idt_list[idt_index].Time;
	float band = idt_list[idt_index].band;
	float t = 0;
	bool found_idt = false;
	bool is_group = (band > time);

	for (int32_t i = 0; i < res_count; i++) // 按组分名从结果表中匹配组分
	{
		std::string res_name = res_list[i].Name;
		if (idt_name == res_name)
		{
			if (is_group) // 组
			{
				area += res_list[i].Area;
				height += res_list[i].Height;
				conc += res_list[i].Conc;
				areaPer += res_list[i].AreaPer;
				found_idt = true;
			}
			else
			{ // 单一组分
				area = res_list[i].Area;
				height = res_list[i].Height;
				conc = res_list[i].Conc;
				areaPer = res_list[i].AreaPer;
				// 扫描紧挨的同名组分，然后求和：
				i++;

				while (i < res_count)
				{
					res_name = res_list[i].Name;

					if (idt_name == res_name)
					{
						area += res_list[i].Area;
						height += res_list[i].Height;
						conc += res_list[i].Conc;
						areaPer += res_list[i].AreaPer;
						i++;
					}
					else
					{
						break;
					}
				}

				found_idt = true;
				break;
			}
		}
	}
	bool calced = false;
	if (!found_idt)
	{
		if (!is_group && qualitBy == BY_SERIAL) //(顺序法定性)单一组分
		{
			area = res_list[idt_index].Area;
			height = res_list[idt_index].Height;
			conc = res_list[idt_index].Conc;
			areaPer = res_list[idt_index].AreaPer;
			calced = true;
		}
		else
		{
			for (int32_t i = 0; i < res_count; i++) // 按保留时间从结果表中匹配组分
			{
				t = res_list[i].RTime;

				if (!is_group && fabs(t - time) < band) // 单一组分
				{
					if (std::string(res_list[i].Name).empty()) // 未知组分
					{
						area = res_list[i].Area;
						height = res_list[i].Height;
						conc = res_list[i].Conc;
						areaPer = res_list[i].AreaPer;
						calced = true;
						break;
					}
				}
			}
		}
	}
	return found_idt || calced;
}
bool GetResp(std::string idt_name, E_QUALITBY qualitBy, double &area, double &height, double &conc, double &areaPer, TDLLIDTINF *idt_inf, TDLLRESINF *res_inf)
{
	int32_t idt_index = IndexOfIdt(idt_name, idt_inf);
	return GetResp(idt_index, qualitBy, area, height, conc, areaPer, idt_inf, res_inf);
}

double GetConc(std::string res_name, bool summed, TDLLRESINF *res_inf)
{
	int32_t res_count = *res_inf->num;
	TDLLResultListItem *res_list = res_inf->head;
	double fConc = 0;
	for (int32_t i = 0; i < res_count; i++)
	{
		if (res_name == res_list[i].Name)
		{
			fConc += res_list[i].Conc;

			if (!summed)
			{
				break;
			}
		}
	}
	if (fConc < 0)
	{
		fConc = 0;
	}
	return fConc;
}

double GetConcBySub(int32_t nBlankMode, E_QUANTBY quantBy, E_QUALITBY qualitBy, E_BASEDON basedOn, double YUnit, int32_t CurveType, std::string idt_name, double &area, double &height, TDLLIDTINF *idt_inf, TDLLRESINF *res_inf, TDLLRESINF *blank_inf)
{
	int32_t idt_index = IndexOfIdt(idt_name, idt_inf);
	double conc = 0;
	double areaPer = 0;
	int32_t blank_count = *blank_inf->num;
	TDLLResultListItem *blank_list = blank_inf->head;

	if (GetResp(idt_index, qualitBy, area, height, conc, areaPer, idt_inf, res_inf))
	{
		conc = GetConc(idt_name, true, res_inf);

		if (blank_count > 0)
		{
			double area_ = 0;
			double height_ = 0;
			double conc_ = 0;
			double areaPer_ = 0;

			if (GetResp(idt_name, qualitBy, area_, height_, conc_, areaPer_, idt_inf, blank_inf))
			{
				if (nBlankMode == SUB_ON_RESP && quantBy != BY_NORMAL && quantBy != BY_S_FACT)
				{
					area -= area_;
					height -= height_;
					TDLLResultListItem res;
					TUkPkFactor uk_factor;
					res.Area = area;
					res.Height = height;
					res.Idno = 1;
					conc = calcResultConc(basedOn, YUnit, CurveType, &idt_inf->head[idt_index], &res, &uk_factor);
				}
				else
				{
					area -= area_;
					height -= height_;
					conc -= conc_;
				}
			}
		}
	}

	return conc;
}

bool GetConcOfGroupBySub(int32_t nBlankMode, E_QUANTBY quantBy, E_QUALITBY qualitBy, E_BASEDON basedOn, double YUnit, int32_t CurveType, TDLLIDTINF *idt_inf, TDLLRESINF *res_inf, TDLLRESINF *blank_inf, int32_t group_index, int32_t group_count, TGroupList *group_list, double &area, double &height, double &conc)
{
	area = 0;
	height = 0;
	conc = 0;
	TDLLResultListItem *result_list = res_inf->head;
	int32_t result_count = *res_inf->num;
	if (group_index >= 0 && group_index < group_count)
	{
		BOOL bContinuous = group_list[group_index].Continuous;

		if (bContinuous) // 连续组
		{
			float tLower = group_list[group_index].tLower;
			float tUpper = group_list[group_index].tUpper;
			int32_t res_index = 0;
			double fA, fH, fC, fCalo = 0;
			std::vector<std::string> v_names;
			std::string grpName = group_list[group_index].Name;

			int32_t name_index = 0;
			while (!std::string(group_list[group_index].IdNames[name_index]).empty())
			{
				v_names.push_back(group_list[group_index].IdNames[name_index++]);
				if (name_index >= B64)
				{
					break;
				}
			}
			while (CalcConcOfContinuousGroupBySub(nBlankMode, quantBy, basedOn, YUnit, CurveType, idt_inf, res_inf, blank_inf, tLower, tUpper, fA, fH, fC, res_index))
			{
				std::string result_name = result_list[res_index].Name;
				if (std::find(v_names.begin(), v_names.end(), result_name) != v_names.end() || result_name == grpName)
				{
					area += fA;
					height += fH;
					conc += fC >= 0 ? fC : 0;
				}
				res_index++;
			}
		}
		else // 间断组
		{
			std::vector<std::string> v_names;
			int32_t name_index = 0;
			while (!std::string(group_list[group_index].IdNames[name_index]).empty())
			{
				v_names.push_back(group_list[group_index].IdNames[name_index++]);
				if (name_index >= B64)
				{
					break;
				}
			}
			double M0 = 0, Mi = 0;

			std::string idt_name;
			double areaI = 0;
			double heightI = 0;
			double concI = 0;

			for (int32_t i = 0; i < (int32_t)v_names.size(); i++)
			{
				idt_name = v_names[i];
				concI = GetConcBySub(nBlankMode, quantBy, qualitBy, basedOn, YUnit, CurveType, idt_name, areaI, heightI, idt_inf, res_inf, blank_inf);
				area += areaI;
				height += heightI;
				conc += concI >= 0 ? concI : 0;
			}
		}
	}
	return true;
}

// 获取综合结果中的连续组的成员含量
bool OneSynConcOfContinuousGroup(float tLower, float tUpper, double &fConc, int &res_index, TDLLRESINF *res_inf, std::vector<TSynResult> &vSynResult)
{
	int32_t res_count = *res_inf->num;
	TDLLResultListItem *res_list = res_inf->head;
	fConc = 0;

	if (res_index < 0 || res_index >= res_count)
	{
		return false;
	}

	float tr = 0;
	bool bTmp = false;
	std::string s_name;

	for (int i = res_index; i < res_count; i++)
	{
		tr = res_list[i].RTime;

		if (tr >= tLower && tr <= tUpper) // 在要求的时间范围中
		{
			res_index = i;
			bTmp = true;
			s_name = res_list[i].Name;

			if (!s_name.empty()) // 为已知峰
			{
				int32_t syn_index = -1;
				for (int32_t j = 0; j < (int32_t)vSynResult.size(); j++)
				{
					if (s_name == vSynResult[j].Name)
					{
						syn_index = j;
						break;
					}
				}

				if (syn_index >= 0)
				{
					fConc = vSynResult[syn_index].Conc;
				}

				i++;

				while (i < res_count && res_list[i].RTime <= tUpper)
				{
					if (s_name == res_list[i].Name)
					{
						res_index = i;
						i++;
					}
					else
					{
						break;
					}
				}
			}

			break;
		}
		else if (tr > tUpper) // 超过要求的时间范围
		{
			break;
		}
	}

	return bTmp;
}

// 求和综合结果中组项目的成员含量
double SumSynConcOfGroup(int32_t group_index, int32_t group_count, TGroupList *group_list, TDLLRESINF *res_inf, std::vector<TSynResult> &vSynResult)
{
	double fConc = 0, fCaloric = 0;

	if (group_index >= 0 && group_index < group_count)
	{
		BOOL bContinuous = group_list[group_index].Continuous;

		if (bContinuous) // 连续组
		{
			float tLower = group_list[group_index].tLower;
			float tUpper = group_list[group_index].tUpper;
			int res_index = 0;
			double fC = 0, fCalo = 0;

			while (OneSynConcOfContinuousGroup(tLower, tUpper, fC, res_index, res_inf, vSynResult))
			{
				fConc += fC;
				res_index++;
			}
		}
		else // 间断组
		{
			std::vector<std::string> v_names;
			int32_t name_index = 0;
			while (!std::string(group_list[group_index].IdNames[name_index]).empty())
			{
				v_names.push_back(group_list[group_index].IdNames[name_index++]);
			}
			std::string s_name;
			int nIdx = -1, idIdx = -1;

			for (int i = 0; i < (int32_t)v_names.size(); i++)
			{
				s_name = v_names[i];
				int32_t syn_index = -1;
				for (int32_t j = 0; j < (int32_t)vSynResult.size(); j++)
				{
					if (s_name == vSynResult[j].Name)
					{
						syn_index = j;
						break;
					}
				}
				if (syn_index >= 0)
				{
					fConc += vSynResult[syn_index].Conc;
				}
			}
		}
	}

	if (fConc < 0)
	{
		fConc = 0;
	}

	return fConc;
}

// 计算综合结果步骤二：处理分组表
bool calcSynResultForGroup(int64_t nHandle, int64_t nMethodHandle, int32_t chn, TDLLIDTINF *idt_inf, TDLLRESINF *res_inf, TUkPkFactor *pUKFactor, std::vector<TSynResult> &vSynResult)
{
	int32_t group_count = 0;
	std::unique_ptr<TGroupList[]> group_list = std::make_unique<TGroupList[]>(B512);
	if (!fetchMethodGroupList(nHandle, nMethodHandle, chn, group_count, group_list, B512))
	{
		PUSH_ERROR("函数 calcSynResultForGroup 调用 fetchMethodGroupList 失败。");
		return false;
	}
	std::unique_ptr<TOrgHead> orgHead = std::make_unique<TOrgHead>();
	std::unique_ptr<TMethodHead> methodHead = std::make_unique<TMethodHead>();

	if (!getOrgHead_(nHandle, orgHead.get()))
	{
		PUSH_ERROR("函数 calcSynResultForGroup 调用 getOrgHead_ 失败。");
		return false;
	}
	E_SUB_TYPE nBlankMode = orgHead.get()->BlankMode;

	if (!fetchMethodHead(nHandle, nMethodHandle, methodHead.get()))
	{
		PUSH_ERROR("函数 calcSynResultForGroup 调用 fetchMethodHead 失败。");
		return false;
	}
	E_BASEDON basedOn = methodHead.get()->EPara.based;
	E_QUANTBY quantBy = methodHead.get()->EPara.quantBy;
	E_QUALITBY qualitBy = methodHead.get()->QualitBy;
	double YUnit = methodHead.get()->YUnit[chn];
	int32_t CurveType = methodHead.get()->CalibHead->CurveType;

	int32_t blank_count = 0;
	TDLLRESINF blank_inf;
	std::unique_ptr<TDLLResultListItem[]> blank_list = std::make_unique<TDLLResultListItem[]>(B512);
	if (!fetchBlankInf(nHandle, chn, blank_inf, blank_count, blank_list))
	{
		PUSH_ERROR("函数 calcSynResultForGroup 调用 fetchBlankInf 失败。");
		return false;
	}

	int32_t nCount0 = (int32_t)vSynResult.size();
	group_count = (methodHead.get()->EPara.grouped) ? group_count : 0;

	if (group_count == 0)
	{
		return true;
	}

	int32_t j = nCount0;

	std::vector<TSynResult> v_cond_result;
	std::vector<TSynResult> v_disc_result;
	std::vector<int32_t> v_cond_indexes;
	std::vector<int32_t> v_disk_indexes;
	std::vector<int32_t> group_indexes;
	for (int32_t i = 0; i < group_count; i++) // 先处理连续组:
	{
		TSynResult synResult;
		STRING_COPY(group_list[i].Name, synResult.Name);
		synResult.Type = group_list[i].Continuous ? ITEM_CONT_GROUP : ITEM_DISC_GROUP;
		synResult.cLower = group_list[i].cLower;
		synResult.cUpper = group_list[i].cUpper;
		synResult.dLimit = 0;
		if (group_list[i].Continuous)
		{
			synResult.Tr = group_list[i].tLower;
			synResult.Band = group_list[i].tUpper;
			v_cond_result.push_back(synResult);
			v_cond_indexes.push_back(i);
		}
		else
		{
			v_disc_result.push_back(synResult);
			v_disk_indexes.push_back(i);
		}
	}
	std::move(v_cond_result.begin(), v_cond_result.end(), std::back_inserter(vSynResult));
	std::move(v_disc_result.begin(), v_disc_result.end(), std::back_inserter(vSynResult));
	std::move(v_cond_indexes.begin(), v_cond_indexes.end(), std::back_inserter(group_indexes));
	std::move(v_disk_indexes.begin(), v_disk_indexes.end(), std::back_inserter(group_indexes));

	double fArea, fHeight, fConc;
	int32_t group_index = -1;

	for (j = nCount0; j < (int32_t)vSynResult.size(); j++)
	{
		group_index = group_indexes[j - nCount0];
		if (!GetConcOfGroupBySub(nBlankMode, quantBy, qualitBy, basedOn, YUnit, CurveType, idt_inf, res_inf, &blank_inf, group_index, group_count, group_list.get(), fArea, fHeight, fConc))
		{
			PUSH_ERROR("函数 calcSynResultForGroup 调用 GetConcOfGroupBySub 失败。");
			return false;
		}
		vSynResult[j].Area = fArea;
		vSynResult[j].Height = fHeight;
		vSynResult[j].Conc = fConc;
	}

	if (blank_count > 0 && nBlankMode == SUB_ON_RESP && (quantBy == BY_NORMAL || quantBy == BY_S_FACT))
	{
		for (j = nCount0; j < (int32_t)vSynResult.size(); j++)
		{
			group_index = group_indexes[j - nCount0];
			fConc = SumSynConcOfGroup(group_index, group_count, group_list.get(), res_inf, vSynResult);
			vSynResult[j].Conc = fConc;
		}
	}
	return true;
}

// 计算未知峰合计
bool sumUnknownPeaks(int64_t nHandle, int64_t nMethodHandle, int32_t chn, double &dArea, double &dHeight, double &dConc, TDLLIDTINF *pIdtInfo, TDLLRESINF *pResInfo, TUkPkFactor *pUKFactor)
{
	std::unique_ptr<TMethodHead> methodHead = std::make_unique<TMethodHead>();

	if (!fetchMethodHead(nHandle, nMethodHandle, methodHead.get()))
	{
		PUSH_ERROR("函数 sumUnknownPeaks 调用 fetchMethodHead 失败。");
		return false;
	}
	E_BASEDON basedOn = methodHead.get()->EPara.based;
	E_QUANTBY quantBy = methodHead.get()->EPara.quantBy;
	double YUnit = methodHead.get()->YUnit[chn];
	int32_t CurveType = methodHead.get()->CalibHead->CurveType;

	if (quantBy == BY_NORMAL || pUKFactor->type <= 0)
	{
		dArea = 0;
		dHeight = 0;
		dConc = 0;
		return true;
	}

	// 计算未知峰合计峰高峰面积
	dArea = 0;
	dHeight = 0;
	for (int i = 0; i < *(pResInfo->num); i++)
	{
		std::string szName = pResInfo->head[i].Name;

		if (pResInfo->head[i].Idno == 0)
		{
			dArea += pResInfo->head[i].Area;
			dHeight += pResInfo->head[i].Height;
		}
	}

	// 未知峰合计峰高峰面积扣除空白结果
	double dBlankArea = 0;
	double dBlankHeight = 0;
	std::unique_ptr<TAnalResult[]> blankList = std::make_unique<TAnalResult[]>(B512);
	int32_t blankCount = 0;
	if (!getOrgBlankResult_(nHandle, chn, &blankList.get()[0], B512, &blankCount))
	{
		PUSH_ERROR("函数 sumUnknownPeaks 调用 getOrgBlankResult_ 失败。");
		return false;
	}
	for (int32_t i = 0; i < blankCount; i++)
	{
		if (blankList.get()[i].Idno == 0)
		{
			dBlankArea += blankList.get()[i].Area;
			dBlankHeight += blankList.get()[i].Height;
		}
	}
	dArea -= dBlankArea;
	dHeight -= dBlankHeight;

	// 计算未知峰合计浓度
	TDLLResultListItem res;
	res.Area = dArea;
	res.Height = dHeight;
	int32_t idt_index = 0;
	if (pUKFactor->type >= 2)
	{
		idt_index = pUKFactor->type - 2;
	}
	dConc = calcResultConc(basedOn, YUnit, CurveType, &pIdtInfo->head[idt_index], &res, pUKFactor);

	return true;
}

// 计算综合结果步骤三：统计未知峰
bool calcSynResult4UnknownPeaks(int64_t nHandle, int64_t nMethodHandle, int32_t chn, TDLLIDTINF *pIdtInfo, TDLLRESINF *pResInfo, TUkPkFactor *pUKFactor, std::vector<TSynResult> &vSynResult)
{
	double dArea = 0;
	double dHeight = 0;
	double dConc = 0;

	if (!sumUnknownPeaks(nHandle, nMethodHandle, chn, dArea, dHeight, dConc, pIdtInfo, pResInfo, pUKFactor))
	{
		PUSH_ERROR("函数 calcSynResult4UnknownPeaks 调用 sumUnknownPeaks 失败。");
		return false;
	}
	TSynResult synResult;
	STRING_COPY(_S_("{未知峰合计}"), synResult.Name);
	synResult.Type = ITEM_SUM_OF_UKS;
	synResult.Area = dArea;
	synResult.Height = dHeight;
	synResult.Conc = dConc;
	vSynResult.push_back(synResult);
	return true;
}

// 综合结果存储到谱图缓冲区
bool storeOrgSynResult(int64_t nHandle, int32_t chn, std::vector<TSynResult> &vSynResult)
{
	int32_t syn_count = (int32_t)vSynResult.size();
	if (syn_count == 0)
	{
		return true;
	}
	if (!setOrgSynResult_(nHandle, chn, vSynResult.data(), syn_count))
	{
		PUSH_ERROR("函数 storeOrgSynResult 调用 setOrgSynResult_ 失败。");
		return false;
	}
	return true;
}

// 积分结果储存到谱图缓冲区
bool storeOrgAnalResult(int64_t nHandle, int32_t chn, TDLLRESINF *pResInfo)
{
	int32_t result_count = *pResInfo->num;
	if (result_count == 0)
	{
		return true;
	}
	std::unique_ptr<TAnalResult[]> pAnalResult = std::make_unique<TAnalResult[]>(result_count);
	for (int32_t i = 0; i < result_count; i++)
	{
		BYTE_COPY(&pResInfo->head[i], &pAnalResult.get()[i], MIN(sizeof(TAnalResult), sizeof(TDLLResultListItem)));
	}
	if (!setOrgAnalResult_(nHandle, chn, pAnalResult.get(), result_count))
	{
		PUSH_ERROR("函数 storeOrgAnalResult 调用 setOrgAnalResult_ 失败。");
		return false;
	}
	return true;
}

#define MAX_CHANNEL 4
void DrawTickMark(int32_t chn, int32_t Time, TICKMARK Mark)
{
	if ((Mark & APEX_TICK) == APEX_TICK)
	{
		if ((chn >= 0) && (chn < MAX_CHANNEL))
		{
			STD_COUT << "DrawTickMark chn=%d" << chn << ", Time=" << Time << ", Mark=" << Mark << STD_ENDL;
		}
	}
}

static bool __bEnglishEdition = true;
// 3.4.21、重新积分
// nMethodHandle = -1，用谱图数据中的方法数据进行积分，否则用指定方法数据中的数据进行积分。
bool analysis_(int64_t nHandle, int64_t nMethodHandle, bool innerCall)
{
	std::lock_guard<std::mutex> lock(analysisMutex); // 锁定互斥锁，保证多线程下顺序执行
	clear_error();
	CHECK_ORG_HANDLE(nHandle);

	std::shared_ptr<TOrgHead> orgHead = std::make_shared<TOrgHead>();

	if (!getOrgHead_(nHandle, orgHead.get()))
	{
		SET_ERROR_(ERR_CODE_ANALYSIS, ERR_MESSAGE_ANALYSIS);
		return false;
	}

	for (int32_t chn = 0; chn < C4; chn++)
	{
		if (isValidChannel(orgHead.get()->Detector, chn))
		{
			// 提取谱图数据
			std::vector<int32_t> DataItems;
			if (!fetchRawData(nHandle, chn, DataItems))
			{
				SET_ERROR_(ERR_CODE_ANALYSIS, ERR_MESSAGE_ANALYSIS);
				return false;
			}
			int32_t DataCount = (int32_t)DataItems.size();
			int32_t DataLength = (int32_t)DataItems.size();

			// 提取方法数据
			std::shared_ptr<TMethodHead> methodHead = std::make_shared<TMethodHead>();
			if (!fetchMethodHead(nHandle, nMethodHandle, methodHead.get()))
			{
				SET_ERROR_(ERR_CODE_ANALYSIS, ERR_MESSAGE_ANALYSIS);
				return false;
			}

			// 提取组分表数据
			int32_t DLLIDTListItemLength = 0;
			TUkPkFactor UkPkFactor;
			BYTE_COPY(&methodHead.get()->UkPkFactor, &UkPkFactor, sizeof(TUkPkFactor));
			std::unique_ptr<TDLLIDTListItem[]> DLLIDTListItem = std::make_unique<TDLLIDTListItem[]>(B512);
			if (!fetchMethodCompList(nHandle, nMethodHandle, chn, UkPkFactor, DLLIDTListItemLength, DLLIDTListItem, B512))
			{
				SET_ERROR_(ERR_CODE_ANALYSIS, ERR_MESSAGE_ANALYSIS);
				return false;
			}

			// 提取分组表数据(分组逻辑放在积分模块之外)
			int32_t DLLGROUPListItemLength = 0;
			std::unique_ptr<TDLLGROUPListItem[]> DLLGROUPListItem = std::make_unique<TDLLGROUPListItem[]>(B512);
			// if (!fetchMethodGroupList(nHandle, nMethodHandle, chn, DLLGROUPListItemLength, DLLGROUPListItem, B512))
			// {
			// 	SET_ERROR_(ERR_CODE_ANALYSIS, ERR_MESSAGE_ANALYSIS);
			// 	return false;
			// }

			// 提取事件表数据
			int32_t DLLTPRGListItemLength = 0;
			std::unique_ptr<TDLLTPRGListItem[]> DLLTPRGListItem = std::make_unique<TDLLTPRGListItem[]>(B512);
			if (!fetchMethodEventList(nHandle, nMethodHandle, chn, DLLTPRGListItemLength, DLLTPRGListItem, B512))
			{
				SET_ERROR_(ERR_CODE_ANALYSIS, ERR_MESSAGE_ANALYSIS);
				return false;
			}

			// 积分数据准备
			float Frequency = orgHead.get()->Frequency;
			float pkNoise = methodHead.get()->IPara.pkNoise;
			float YUnit = methodHead.get()->YUnit[chn];
			int32_t CurveType = methodHead.get()->CalibHead[chn].CurveType;
			TRAWBAG RawBag;
			TSMPBAG SmpBag;
			TDLLEPINF epInf;
			TDLLIPINF ipInf;
			TDLLTPRGINF DLLTPRGInf;
			TDLLGRPINF DLLGRPInf;
			TDLLIDTINF DLLIDTInf;
			TDLLRESINF DLLRESInf;
			// 因为积分模块BUG，预留1个单元的TDLLResultListItem在数据前面。
			std::unique_ptr<TDLLResultListItem[]> DLLResultListItem = std::make_unique<TDLLResultListItem[]>(B2048 + 1);
			int32_t DLLResultListLength = 0;

			ipInf.ipara = &methodHead.get()->IPara;
			ipInf.tprgInf = &DLLTPRGInf;
			ipInf.ipara->testPkDrift = ipInf.ipara->pkDrift;
			ipInf.ipara->testPkWidth = ipInf.ipara->pkWidth;
			ipInf.ipara->testPkNoise = ipInf.ipara->pkNoise;
			ipInf.ipara->stopTime = (float)(1.0 * DataLength / Frequency / 60);

			DLLIDTInf.head = DLLIDTListItem.get();
			DLLIDTInf.len = B512;
			DLLIDTInf.num = &DLLIDTListItemLength;

			DLLGRPInf.head = DLLGROUPListItem.get();
			DLLGRPInf.len = B512;
			DLLGRPInf.num = &DLLGROUPListItemLength;
			epInf.epara = &methodHead.get()->EPara;
			epInf.grpInf = &DLLGRPInf;

			DLLTPRGInf.head = DLLTPRGListItem.get();
			DLLTPRGInf.len = B512;
			DLLTPRGInf.num = &DLLTPRGListItemLength;

			DLLRESInf.head = &DLLResultListItem.get()[1];
			DLLRESInf.len = B2048;
			DLLRESInf.num = &DLLResultListLength;

			RawBag.head = DataItems.data();
			RawBag.time = &DataCount;
			RawBag.len = DataLength;
			RawBag.freq = &Frequency;
			SmpBag.Base = NULL;
			SmpBag.baseMaxTime = 0;

			SmpBag.metric = &methodHead.get()->metric;
			SmpBag.rawbag = &RawBag;

			CAnalysis analyzer;

			TAPPSetting APPSetting = {
				0,
			};
			STRING_COPY("24.07", APPSetting.Version);
			APPSetting.LanguageID = (__bEnglishEdition) ? _ENU_ : _CHS_;
			uint64_t lParam = (uint64_t)&APPSetting;
			analyzer.SetMiscellaneous(-1, 0, lParam);

			if (!analyzer.InitAnalPool(MAX_CHANNEL + 2, MAX_CHANNEL, &DrawTickMark))
			{
				SET_ERROR_(ERR_CODE_ANALYSIS, ERR_MESSAGE_ANALYSIS);
				return false;
			}
			bool analyzerOpened = analyzer.OpenAnal(chn, &SmpBag, &ipInf, &epInf, &DLLIDTInf, &DLLRESInf, NULL);
			if (analyzerOpened)
			{
				TMiscellaneous miscellaneous;
				miscellaneous.QualitMode = 0;
				miscellaneous.RefEnabled = true; // 标准版无参考峰修正功能
				miscellaneous.IstdAsRef = false; // 白酒版的内标物即为参考峰
				miscellaneous.IdtWindow = 0;
				miscellaneous.IdtTimeOfs = 0;
				BYTE_COPY(&UkPkFactor, &(miscellaneous.UkPkFactor), sizeof(TUkPkFactor));
				miscellaneous.XMinUnitK = 60;
				miscellaneous.YMinUnit = methodHead.get()->YUnit[chn];
				analyzer.SetMiscellaneous(chn, (uint64_t)&miscellaneous, 0);

				analyzer.StartAnal(chn);
				CODE nAnalCode = ANAL_NOP;

				do
				{
					try
					{
						nAnalCode = analyzer.ExecAnal(chn);
					}
					catch (...)
					{
						analyzer.StopAnal(chn);
						PUSH_ERROR("内核积分模块出错!");
						break;
					}

				} while (nAnalCode != ANAL_STOP && nAnalCode != ANAL_ERROR);

				analyzer.CloseAnal(chn);
				if (has_error())
				{
					SET_ERROR_(ERR_CODE_ANALYSIS, ERR_MESSAGE_ANALYSIS);
					return false;
				}
				// 计算物质浓度
				E_BASEDON based = methodHead.get()->EPara.based;
				if (!calcOrgResultConc(based, YUnit, CurveType, &DLLIDTInf, &DLLRESInf, &UkPkFactor))
				{
					SET_ERROR_(ERR_CODE_ANALYSIS, ERR_MESSAGE_ANALYSIS);
					return false;
				}
				// 组分表排序还原恢复，结果表的Idno应指向未排序前的组分索引号
				if (!restoreIdtSortAction(&DLLIDTInf, &DLLRESInf))
				{
					SET_ERROR_(ERR_CODE_ANALYSIS, ERR_MESSAGE_ANALYSIS);
					return false;
				}
				// 计算水平基线积分(扩展手动事件)
				if (!calcHorzBaseLine(nHandle, nMethodHandle, chn, based, YUnit, CurveType, &RawBag, &DLLIDTInf, &DLLRESInf, &UkPkFactor))
				{
					SET_ERROR_(ERR_CODE_ANALYSIS, ERR_MESSAGE_ANALYSIS);
					return false;
				}

				// 存储积分结果到谱图
				if (!storeOrgAnalResult(nHandle, chn, &DLLRESInf))
				{
					SET_ERROR_(ERR_CODE_ANALYSIS, ERR_MESSAGE_ANALYSIS);
					return false;
				}
				
				std::vector<TSynResult> vSynResult;
				// 计算综合结果步骤一：处理组分表
				if (!calcSynResultForIdt(nHandle, nMethodHandle, chn, &DLLIDTInf, &DLLRESInf, &UkPkFactor, vSynResult))
				{
					SET_ERROR_(ERR_CODE_ANALYSIS, ERR_MESSAGE_ANALYSIS);
					return false;
				}

				// 计算综合结果步骤二：处理分组表
				if (!calcSynResultForGroup(nHandle, nMethodHandle, chn, &DLLIDTInf, &DLLRESInf, &UkPkFactor, vSynResult))
				{
					SET_ERROR_(ERR_CODE_ANALYSIS, ERR_MESSAGE_ANALYSIS);
					return false;
				}

				// 计算综合结果步骤三：统计未知峰
				if (!calcSynResult4UnknownPeaks(nHandle, nMethodHandle, chn, &DLLIDTInf, &DLLRESInf, &UkPkFactor, vSynResult))
				{
					SET_ERROR_(ERR_CODE_ANALYSIS, ERR_MESSAGE_ANALYSIS);
					return false;
				}

				// 存储综合结果到谱图
				if (!storeOrgSynResult(nHandle, chn, vSynResult))
				{
					SET_ERROR_(ERR_CODE_ANALYSIS, ERR_MESSAGE_ANALYSIS);
					return false;
				}
			}
			else
			{
				SET_ERROR_(ERR_CODE_ANALYSIS, ERR_MESSAGE_ANALYSIS);
				return false;
			}
		}
	}
	return true;
}
bool analysis(int64_t nHandle, int64_t nMethodHandle)
{
	return analysis_(nHandle, nMethodHandle, false);
}